package github.saw96x.remoting.transport.socket;

import github.saw96x.common.exception.RpcException;
import github.saw96x.common.extension.ExtensionLoader;
import github.saw96x.registry.ServiceDiscovery;
import github.saw96x.remoting.pojo.RpcRequest;
import github.saw96x.remoting.transport.RpcRequestTransport;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * @author Saw96x
 * @date 2022/3/18 8:47
 */
@AllArgsConstructor
@Slf4j
public class SocketRpcClient implements RpcRequestTransport {
  private final ServiceDiscovery serviceDiscovery;

  public SocketRpcClient() {
    this.serviceDiscovery = ExtensionLoader.getExtensionLoader(ServiceDiscovery.class).getExtension("zk");
  }

  @Override
  public Object sendRpcRequest(RpcRequest rpcRequest) {
    InetSocketAddress inetSocketAddress = serviceDiscovery.lookupService(rpcRequest);
    try (Socket socket = new Socket()) {
      socket.connect(inetSocketAddress);
      ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
      // 通过输出流向服务端发送rpc请求
      objectOutputStream.writeObject(rpcRequest);
      ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
      // 通过输入流读取服务端的rpc响应
      return objectInputStream.readObject();
    } catch (IOException | ClassNotFoundException e) {
      throw new RpcException("调用服务失败:", e);
    }
  }
}
